# coding=utf-8
# 代码文件：client/ui/file_list_frame.py

"""文档列表窗口"""
import wx
import wx.grid
import io
import requests
from ui.my_frame import MyFrame
from ui.request_frame import RequestFrame
from ui.file_list_gridtable import FileListGridTable
from services.auth_service import AuthService  # 引入 AuthService

# 文档类别
CATEGORYS = ['all', 'physics', 'mathematics', 'computerscience', 'chemistry', 'biology']


class FileListFrame(MyFrame):
    def __init__(self):
        super().__init__(title='文档列表窗口', size=(1000, 700))

        # 从服务器获取所有文档（暂时
        try:
            self.data = AuthService.fetch_files()
        except Exception as e:
            self.data = []
            print(f"Failed to fetch files: {e}")

        # 创建分隔窗口
        splitter = wx.SplitterWindow(self.contentpanel, style=wx.SP_3DBORDER)
        self.leftpanel = self.createleftpanel(splitter)
        self.rightpanel = self.createrightpanel(splitter)
        splitter.SplitVertically(self.leftpanel, self.rightpanel, 630)

        # 设置最小窗口尺寸
        splitter.SetMinimumPaneSize(630)

        # 设置整个窗口布局是垂直 Box 布局
        vbox = wx.BoxSizer(wx.VERTICAL)
        self.contentpanel.SetSizer(vbox)

        # 添加顶部对象（topbox）到 vbox
        vbox.Add(self.createtopbox(), 1, flag=wx.EXPAND | wx.ALL, border=20)
        # 添加底部对象（splitter）到 vbox
        vbox.Add(splitter, 1, flag=wx.EXPAND | wx.ALL, border=10)

        # 在当前创建（Frame 对象）创建并添加默认状态栏
        self.CreateStatusBar()
        self.SetStatusText('准备就绪')

    def createtopbox(self):
        """创建顶部布局管理器 topbox"""

        # 创建静态文本
        pc_st = wx.StaticText(parent=self.contentpanel, label='选择文档类别：', style=wx.ALIGN_RIGHT)
        # 创建按钮对象
        search_btn = wx.Button(parent=self.contentpanel, label='查询')
        reset_btn = wx.Button(parent=self.contentpanel, label='重置')
        choice = wx.Choice(self.contentpanel, choices=CATEGORYS, name='choice')
        # 绑定事件处理
        self.Bind(wx.EVT_BUTTON, self.search_btn_onclick, search_btn)
        self.Bind(wx.EVT_BUTTON, self.reset_btn_onclick, reset_btn)

        box = wx.BoxSizer(wx.HORIZONTAL)
        box.AddSpacer(200)
        box.Add(pc_st, 1, flag=wx.FIXED_MINSIZE | wx.ALL, border=10)
        box.Add(choice, 1, flag=wx.EXPAND | wx.ALL, border=5)
        box.Add(search_btn, 1, flag=wx.EXPAND | wx.ALL, border=5)
        box.Add(reset_btn, 1, flag=wx.EXPAND | wx.ALL, border=5)
        box.AddSpacer(260)

        return box

    def createleftpanel(self, parent):
        """创建分隔窗口中的左侧面板"""

        panel = wx.Panel(parent)

        # 创建网格对象
        grid = wx.grid.Grid(panel, name='grid')
        # 绑定网格事件处理
        self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.selectrow_handler)
        self.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self.selectrow_handler)

        # 初始化网格
        self.initgrid()

        # 创建水平 Box 布局管理器
        box = wx.BoxSizer()
        # 设置水平 Box 布局管理器网格 grid
        box.Add(grid, 1, flag=wx.ALL, border=5)
        panel.SetSizer(box)

        return panel

    def createrightpanel(self, parent):
        """创建分隔窗口中的右侧面板"""

        panel = wx.Panel(parent, style=wx.TAB_TRAVERSAL | wx.BORDER_DOUBLE)
        panel.SetBackgroundColour(wx.WHITE)

            # 检查数据是否为空
        if not self.data:
            print("No data available to display in the right panel.")
            static_text = wx.StaticText(panel, label="暂无数据")
            vbox = wx.BoxSizer(wx.VERTICAL)
            vbox.Add(static_text, 1, flag=wx.CENTER | wx.ALL, border=10)
            panel.SetSizer(vbox)
            return panel
        
            # 显示选择的图片
        try:
            # 从服务器返回的 URL 加载图片
            image_url = self.data[0]['thumbnail_url']  # 假设服务器返回的字段是 'thumbnail_url'
            response = requests.get(image_url)
            response.raise_for_status()  # 检查请求是否成功
            image_stream = io.BytesIO(response.content)
            image = wx.Image(image_stream, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
            image_sbitmap = wx.StaticBitmap(panel, bitmap=image, name='image_sbitmap')
        except (KeyError, IndexError, requests.RequestException) as e:
            print(f"Error loading image from URL: {e}")
            image_sbitmap = wx.StaticText(panel, label="暂无图片")
            
        # 文档作者
        author = "作者：{0}".format(self.data[0]['author'])
        author_st = wx.StaticText(panel, label=author, name='author')
        # 文档期刊
        journal = "作者：{0}".format(self.data[0]['journal'])
        journal_st = wx.StaticText(panel, label=journal, name='journal')
        # 文档描述
        descn = "作者：{0}".format(self.data[0]['descn'])
        descn_st = wx.StaticText(panel, label=descn, name='descn')

        # 创建按钮对象
        addrequest_btn = wx.Button(panel, label='添加请求')
        seerequest_btn = wx.Button(panel, label='查看请求')
        # 绑定事件处理
        self.Bind(wx.EVT_BUTTON, self.addrequest_btn_onclick, addrequest_btn)
        self.Bind(wx.EVT_BUTTON, self.seerequest_btn_onclick, seerequest_btn)

        # 创建垂直 Box 布局管理器
        box = wx.BoxSizer(wx.VERTICAL)
        box.AddSpacer(50)
        box.Add(image_sbitmap, 1, flag=wx.CENTER | wx.ALL, border=30)
        box.AddSpacer(50)
        box.Add(author_st, 1, flag=wx.EXPAND | wx.ALL, border=10)
        box.Add(journal_st, 1, flag=wx.EXPAND | wx.ALL, border=10)
        box.Add(descn_st, 1, flag=wx.EXPAND | wx.ALL, border=10)
        box.AddSpacer(20)
        box.Add(addrequest_btn, 1, flag=wx.EXPAND | wx.ALL, border=10)
        box.Add(seerequest_btn, 1, flag=wx.EXPAND | wx.ALL, border=10)

        return panel

    def initgrid(self):
        """初始化网格对象"""

        # 通过网格名称获得网格对象
        grid = self.FindWindowByName('grid')

        # 打印调试信息
        print("Initializing grid with data:", self.data)
        print("Grid object:", grid)

        # 创建网格中所需的表格
        table = FileListGridTable(self.data)
        # 设置网格的表格属性
        grid.SetTable(table, True)

        # 设置网格所有行高
        rowsizeinfo = wx.grid.GridSizesInfo(40, [])
        grid.SetRowSizes(rowsizeinfo)
        # 设置网格所有列宽
        colsizeinfo = wx.grid.GridSizesInfo(0, [100, 80, 130, 200])
        grid.SetColSizes(colsizeinfo)
        # 设置单元格默认字体
        grid.SetDefaultCellFont(wx.Font(11, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                                        wx.FONTWEIGHT_NORMAL, faceName='微软雅黑'))
        # 设置行和列标题的默认字体
        grid.SetLabelFont(wx.Font(9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                                  wx.FONTWEIGHT_NORMAL, faceName='微软雅黑'))
        # 设置网格选择模式为行选择
        grid.SetSelectionMode(wx.grid.Grid.SelectRows)
        # 设置不能通过拖动改变行高度
        grid.DisableDragRowSize()
        # 设置不能通过拖动改变列高度
        grid.DisableDragColSize()

    def search_btn_onclick(self, event):
        """查询按钮事件处理"""

        # 通过名称查询 choice 控件
        choice = self.FindWindowByName('choice')
        # 获得选中类别索引
        selectcatidx = choice.GetSelection()
        if selectcatidx >= 0:
            # 获得选中的文档类别
            catname = CATEGORYS[selectcatidx]

            # 根据类别查询文档
            try:
                if catname == 'all':  # 如果选择 "all"，查询所有文档
                    self.data = AuthService.fetch_files()
                else:  # 否则按类别查询
                    self.data = AuthService.fetch_files(catname)
            except Exception as e:
                self.data = []
                print(f"Failed to fetch files by category: {e}")

            # 初始化网格
            self.initgrid()

    def reset_btn_onclick(self, event):
        """重置按钮事件处理"""

        # 查询所有文档
        try:
            self.data = AuthService.fetch_files()
        except Exception as e:
            self.data = []
            print(f"Failed to fetch files: {e}")

        # 初始化网格
        self.initgrid()

    def addrequest_btn_onclick(self, event):
        """添加到请求事件处理"""

        if len(self.selecteddata) == 0:
            self.SetStatusText('请先选择文档')
            return

        # 获得选择的文档 id
        fileid = self.selecteddata['fileid']
        if fileid in self.request.keys():  # 判断请求中已经有该文档
            # 获得文档数量
            quantity = self.request[fileid]
            self.request[fileid] = (quantity + 1)
        else:  # 请求中还没有该文档
            self.request[fileid] = 1

        # 提交请求到服务器
        try:
            session_data = AuthService.load_session()
            short_jwt = session_data.get('short_jwt')
            if not short_jwt:
                raise Exception('短时 JWT 不存在，请重新登录')

            AuthService.create_request(self.request, short_jwt)
            self.SetStatusText(f'文档 {fileid} 添加到请求成功')
        except Exception as e:
            self.SetStatusText(f'文档 {fileid} 添加到请求失败: {e}')
            print(f"Failed to add request: {e}")

        print(self.request)

    def seerequest_btn_onclick(self, event):
        """查看添加到请求事件处理"""

        next_frame = RequestFrame(self.request, self)
        next_frame.Show()
        self.Hide()

    def selectrow_handler(self, event):
        """选择网格行事件处理"""

        srowidx = event.GetRow()
        if srowidx >= 0:
            print(self.data[srowidx])
            self.selecteddata = self.data[srowidx]
            self.SetStatusText('选择第{0}行数据'.format(srowidx + 1))

        try:
            # 从服务器返回的 URL 加载图片
            image_url = self.data[srowidx]['thumbnail_url']  # 假设服务器返回的字段是 'thumbnail_url'
            response = requests.get(image_url)
            response.raise_for_status()  # 检查请求是否成功
            image_stream = io.BytesIO(response.content)
            image = wx.Image(image_stream, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        except (KeyError, IndexError, requests.RequestException) as e:
            print(f"Error loading image from URL: {e}")
            image = wx.Bitmap(100, 100)  # 使用占位图片或空白图片
        
            # 通过名称查询子窗口
            image_sbitmap = wx.FindWindowByName('image_sbitmap')
            image_sbitmap.SetBitmap(image)

            # 文档作者
            author = "作者：{0}".format(self.data[0]['author'])
            author_st = wx.FindWindowByName('author')
            author_st.SetLabelText(author)

            # 文档期刊
            journal = "作者：{0}".format(self.data[0]['journal'])
            journal_st = wx.FindWindowByName('journal')
            journal_st.SetLabelText(journal)

            # 文档描述
            descn = "作者：{0}".format(self.data[0]['descn'])
            descn_st = wx.wx.FindWindowByName('descn')
            descn_st.SetLabelText(descn)

            self.rightpanel.Layout()

        event.Skip()
